import numpy as np
import os
import pickle
import shutil

"""
保存系统:存储地图数据以及加载地图数据
"""


class SaveManager:
    def __init__(self, world_save_path, compressed=False):
        self.world_save_path, self.compressed = world_save_path, compressed

        self.chunks_save_path = os.path.join(world_save_path, "chunks")
        self.player_info_save_path = os.path.join(world_save_path, "player_info")

    def delete_save(self):
        if os.path.exists(self.world_save_path):
            shutil.rmtree(self.world_save_path)

    def create_directory(self):
        if not os.path.exists(self.chunks_save_path):
            os.makedirs(self.chunks_save_path)
        if not os.path.exists(self.player_info_save_path):
            os.makedirs(self.player_info_save_path)

    def get_chunk_path(self, chunk_pos):
        if not self.compressed:
            return os.path.join(self.chunks_save_path, f"{chunk_pos}.npy")
        else:
            return os.path.join(self.chunks_save_path, f"{chunk_pos}.npz")

    def get_inventory_path(self):
        return os.path.join(self.player_info_save_path, "inventory.pkl")

    def get_transform_path(self):
        return os.path.join(self.player_info_save_path, "transform.pkl")

    def is_chunk_data_exists(self, chunk_pos):
        return os.path.exists(self.get_chunk_path(chunk_pos))

    def is_inventory_data_exists(self):
        return os.path.exists(self.get_inventory_path())

    def is_transform_data_exists(self):
        return os.path.exists(self.get_transform_path())

    def save_chunk_data(self, chunk_pos, data):
        if not self.compressed:
            # thread = threading.Thread(target=np.save, args=(self.get_chunk_path(chunk_pos), data))
            # thread.start()
            np.save(self.get_chunk_path(chunk_pos), data)
        else:
            # thread = threading.Thread(target=np.savez_compressed, args=(self.get_chunk_path(chunk_pos), data))
            # thread.start()
            np.savez_compressed(self.get_chunk_path(chunk_pos), array=data)

    def load_chunk_data(self, chunk_pos):
        if not self.is_chunk_data_exists(chunk_pos):
            return None
        else:
            if not self.compressed:
                return np.load(self.get_chunk_path(chunk_pos))
            else:
                return np.load(self.get_chunk_path(chunk_pos))['arr_0']

    def save_inventory_data(self, inventory_data):
        with open(self.get_inventory_path(), 'wb') as file:
            pickle.dump(inventory_data, file)

    def load_inventory_data(self):
        if not self.is_inventory_data_exists():
            return None
        with open(self.get_inventory_path(), 'rb') as file:
            return pickle.load(file)

    def save_transform_data(self, transform_data):
        with open(self.get_transform_path(), 'wb') as file:
            pickle.dump(transform_data, file)

    def load_transform_data(self):
        if not self.is_transform_data_exists():
            return None
        with open(self.get_transform_path(), 'rb') as file:
            return pickle.load(file)
